#include "System.h"
#include <iostream>
#include "Mesh.h"
#include "InitCondition.h"
#include "Output.h"

Real BoundaryCondtion(Real x, Real t)
{
	return 0;
}
System::System(int steps, int num_cells) :_steps(steps), _num_cells(num_cells)
{
	_mesh = std::make_shared<Mesh>(0, 1, num_cells);
	_u.resize(num_cells);
	_rhs.resize(num_cells);
}

System::~System()
{
}

void System::Init()
{
	std::cout << "System::Init()" << std::endl;
	InitCondition{}.Execute(_u);
}
void System::Run()
{
	for (size_t i = 0; i < _steps; i++)
	{
		std::cout << "Step: " << i << std::endl;
		Solve();
		TimeIntegrade();
		_current_time += _dt;
	}

	Output{}(*this);

}

void System::Solve()
{
	Real flux_l, flux_r;
	for (size_t i = 0; i < _num_cells; i++)
	{
		if (i == 0) {
			flux_l = BoundaryCondtion(_mesh->_start, _current_time);
			flux_r = _u[i + 1];
		}
		else if (i == _num_cells-1) {
			flux_l = _u[i];
			flux_r = BoundaryCondtion(_mesh->_end, _current_time);;
		}
		else
		{
			flux_l = _u[i];
			flux_r = _u[i + 1];
		}

		_rhs[i] = (flux_r - flux_l) / _mesh->dh();
	}
}

void System::TimeIntegrade()
{
	for (size_t i = 0; i < _num_cells; i++)
	{
		_u[i] += _rhs[i] * _dt;
	}
}
